package com.fivetrue.location;

import java.util.List;
import java.util.Locale;

import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;

public class LocationControlManager{

	private final String PROVIDER_NULL_ERR = "Location Provider is empty";
	private final String LOCATION_MANAGER_NULL_ERR = "Location Manager is null";
	private final String LOCATION_DATA_NULL_ERR = "Location DATA is null";
	private final String OK = "OK";
	private final String TAG = getClass().getName();

	private final long MIN_TIME = 500;
	private final float MIN_DISTANCE = 1;
	private final int NUM_OF_ADDRESS = 1;

	private Context mContext = null;
	private LocationManager mLocation = null;
	private LocationListener mLocationListener = null;
	private String mProvider = null;

	private Location mLocationData = null;


	static public LocationControlManager getInstance(Context context){
		return new LocationControlManager(context);
	}

	private LocationControlManager(Context context){
		mContext = context;
		mLocation = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);

		Criteria c = new Criteria();
		mProvider = mLocation.getBestProvider(c, true);

		if(mProvider == null || !mLocation.isProviderEnabled(mProvider)){
			List<String> list = mLocation.getAllProviders();

			for(int i = 0 ; i < list.size() ; i++){
				String temp = list.get(i);

				if(mLocation.isProviderEnabled(temp)){
					mProvider = temp;
				}
			}
		}
		requestLocationUpdate();
	}

	public static boolean isMockLocationSet(Context context) { 
		if (Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).contentEquals("1")) { 
			return true;  
		} 
		else { 
			return false;                     
		} 
	} 
	public void stop(){
		if(mLocation != null){
			mLocation.removeUpdates(mListener);
		}
	}
	
	public void start(){
		requestLocationUpdate();
	}
	
	public Location getLastLocation(){
		if(mLocation != null){
			mLocationData = mLocation.getLastKnownLocation(mProvider);
			if(mLocationData == null){
				Log.e(TAG, LOCATION_DATA_NULL_ERR);
			}
		}else{
			Log.e(TAG, LOCATION_MANAGER_NULL_ERR);
		}
		return mLocationData;
	}

	public Location getCurrenLocationData(){
		if(mLocationData != null){
			return mLocationData;
		}else{
			Log.e(TAG, LOCATION_DATA_NULL_ERR);
			mLocationData = mLocation.getLastKnownLocation(mProvider);
			return mLocationData;
		}
	}
	
	public void requestLocationUpdate(){
		if(mLocation != null && mProvider != null){
			if(mListener != null){
					mLocation.requestLocationUpdates(mProvider, MIN_TIME, MIN_DISTANCE, mListener);
			}
		}
	}
	
	public void setLocationListener(LocationListener ll){
		mLocationListener = ll;
	}
	
	public void removeLocationListener(){
		mLocationListener = null;
	}

	public String getAddress(){
		String address = null;

		Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());

		List<Address> list = null;

		try{
			list = geocoder.getFromLocation(mLocationData.getLatitude(), mLocationData.getLongitude(), NUM_OF_ADDRESS);
		}catch(Exception e){
			e.printStackTrace();
		}

		if(list.size() > 0){
			Address addr = list.get(0);
			StringBuilder stb = new StringBuilder();
			stb.append(addr.getCountryName()).append(" ")
			.append(addr.getPostalCode()).append(" ")
			.append(addr.getLocality()).append(" ")
			.append(addr.getThoroughfare()).append(" ")
			.append(addr.getFeatureName()).append(" ");
			address = stb.toString();
		}
		return address;
	}
	
	private LocationListener mListener = new LocationListener(){

		@Override
		public void onLocationChanged(Location location) {
			// TODO Auto-generated method stub
			if(mLocationListener != null){
				mLocationListener.onLocationChanged(location);
			}
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub
			if(mLocationListener != null){
				mLocationListener.onStatusChanged(provider,status,extras);
			}
		}

		@Override
		public void onProviderEnabled(String provider) {
			// TODO Auto-generated method stub
			if(mLocationListener != null){
				mLocationListener.onProviderEnabled(provider);
			}
		}

		@Override
		public void onProviderDisabled(String provider) {
			// TODO Auto-generated method stub
			if(mLocationListener != null){
				mLocationListener.onProviderDisabled(provider);
			}
		}
		
	};
}
